﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace QT.Security
{
    /// <summary>
    /// 3DES操作类
    /// </summary>
    public class TripleDESHelper
    {
        private static string sKey = @"MKEaFaW.#=?=7gKv[l/E6n\m"; //密钥
        private static string sIV = @"nH<Q-nqE"; //密钥向量

        #region 加密

        #region 加密文件

        /// <summary>
        /// 加密文件
        /// </summary>
        /// <param name="inFileName">输入文件</param>
        /// <param name="outFileName">输出文件</param>
        /// <param name="Key">加密密钥</param>
        /// <param name="IV">向量</param>
        /// <returns>bool</returns>
        public static bool EncryptFile(string inFileName, string outFileName, string Key, string IV)
        {
            FileStream fin = new FileStream(inFileName, FileMode.Open, FileAccess.Read);
            FileStream fout = null;
            try
            {
                fout = new FileStream(outFileName, FileMode.OpenOrCreate, FileAccess.Write);
            }
            catch
            {
                return false;
            }
            fout.SetLength(0);

            byte[] bin = new byte[100];
            long rdlen = 0;
            long totlen = fin.Length;
            int len;

            try
            {
                TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
                DES.Key = Encoding.UTF8.GetBytes(Key);
                DES.IV = Encoding.UTF8.GetBytes(IV);
                CryptoStream encStream = new CryptoStream(fout, DES.CreateEncryptor(), CryptoStreamMode.Write);

                while (rdlen < totlen)
                {
                    len = fin.Read(bin, 0, 100);
                    encStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }

                encStream.Close();
            }
            catch
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 加密文件
        /// </summary>
        /// <param name="inFileName">输入文件</param>
        /// <param name="outFileName">输出文件</param>
        /// <param name="Key">加密密钥</param>
        /// <returns>bool</returns>
        public static bool EncryptFile(string inFileName, string outFileName, string Key)
        {
            return EncryptFile(inFileName, outFileName, Key, sIV);
        }

        /// <summary>
        /// 加密文件
        /// </summary>
        /// <param name="inFileName">输入文件</param>
        /// <param name="outFileName">输出文件</param>
        /// <returns>bool</returns>
        public static bool EncryptFile(string inFileName, string outFileName)
        {
            return EncryptFile(inFileName, outFileName, sKey, sIV);
        }

        #endregion

        #region 加密字符串

        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="encryptValue">待加密的字符串</param>
        /// <param name="Key">加密密钥</param>
        /// <param name="IV">向量</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源字符串</returns>
        public static string EncryptString(string encryptValue, string Key, string IV)
        {
            try
            {
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
                des.Key = Encoding.UTF8.GetBytes(Key);
                des.IV = Encoding.UTF8.GetBytes(IV);
                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.PKCS7;

                byte[] valBytes = Encoding.UTF8.GetBytes(encryptValue);
                ICryptoTransform transform = des.CreateEncryptor();

                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);


                cs.Write(valBytes, 0, valBytes.Length);
                cs.FlushFinalBlock();
                byte[] returnBytes = ms.ToArray();
                cs.Close();
                ms.Close();

                return Convert.ToBase64String(returnBytes);
            }
            catch
            {
                return encryptValue;
            }
        }

        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="encryptValue">待加密的字符串</param>
        /// <param name="Key">加密密钥</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源字符串</returns>
        public static string EncryptString(string encryptValue, string Key)
        {
            return EncryptString(encryptValue, Key, sIV);
        }

        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <param name="encryptValue">待加密的字符串</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源字符串</returns>
        public static string EncryptString(string encryptValue)
        {
            return EncryptString(encryptValue, sKey, sIV);
        }

        #endregion

        #endregion

        #region 解密

        #region 解密文件

        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inFileName">输入文件</param>
        /// <param name="outFileName">输入文件</param>
        /// <param name="Key">解密密钥</param>
        /// <param name="IV">向量</param>
        /// <returns>bool</returns>
        public static bool DecryptFile(string inFileName, string outFileName, string Key, string IV)
        {
            FileStream fin = new FileStream(inFileName, FileMode.Open, FileAccess.Read);
            FileStream fout = null;
            try
            {
                fout = new FileStream(outFileName, FileMode.OpenOrCreate, FileAccess.Write);
            }
            catch
            {
                return false;
            }
            fout.SetLength(0);

            byte[] bin = new byte[100];
            long rdlen = 0;
            long totlen = fin.Length;
            int len;

            try
            {
                TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider();
                DES.Key = Encoding.UTF8.GetBytes(Key);
                DES.IV = Encoding.UTF8.GetBytes(IV);
                CryptoStream decStream = new CryptoStream(fout, DES.CreateDecryptor(), CryptoStreamMode.Write);

                while (rdlen < totlen)
                {
                    len = fin.Read(bin, 0, 100);
                    decStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }

                decStream.Close();
            }
            catch
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inFileName">输入文件</param>
        /// <param name="outFileName">输入文件</param>
        /// <param name="Key">解密密钥</param>
        /// <returns>bool</returns>
        public static bool DecryptFile(string inFileName, string outFileName, string Key)
        {
            return DecryptFile(inFileName, outFileName, Key, sIV);
        }

        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inFileName">输入文件</param>
        /// <param name="outFileName">输入文件</param>
        /// <returns>bool</returns>
        public static bool DecryptFile(string inFileName, string outFileName)
        {
            return DecryptFile(inFileName, outFileName, sKey, sIV);
        }

        #endregion

        #region 解密字符串

        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <param name="decryptedValue">待解密的字符串</param>
        /// <param name="Key">解密密钥</param>
        /// <param name="IV">向量</param>
        /// <returns>解密成功返回解密后的字符串，失败返回源字符串</returns>
        public static string DecryptString(string decryptedValue, string Key, string IV)
        {
            try
            {
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
                des.Key = Encoding.UTF8.GetBytes(Key);
                des.IV = Encoding.UTF8.GetBytes(IV);
                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.PKCS7;

                byte[] valBytes = Convert.FromBase64String(decryptedValue);
                ICryptoTransform transform = des.CreateDecryptor();

                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
                cs.Write(valBytes, 0, valBytes.Length);
                cs.FlushFinalBlock();
                byte[] returnBytes = ms.ToArray();
                cs.Close();
                ms.Close();

                return Encoding.UTF8.GetString(returnBytes);
            }
            catch
            {
                return decryptedValue;
            }
        }

        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <param name="decryptedValue">待解密的字符串</param>
        /// <param name="Key">解密密钥</param>
        /// <returns>解密成功返回解密后的字符串，失败返回源字符串</returns>
        public static string DecryptString(string decryptedValue, string Key)
        {
            return DecryptString(decryptedValue, Key, sIV);
        }

        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <param name="decryptedValue">待解密的字符串</param>
        /// <returns>解密成功返回解密后的字符串，失败返回源字符串</returns>
        public static string DecryptString(string decryptedValue)
        {
            return DecryptString(decryptedValue, sKey, sIV);
        }

        #endregion

        #endregion
    }
}
